﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using LTorrent.Tracker;
using LTorrent.Torrent;
using LTorrent.Extensions;
using LTorrent.Peers;
//Отследить, нужны ли нижние двое
/*
using LTorrent.Torrent.BEncode;
using LTorrent.Torrent.File;*/

//Управляющий класс - обрабатывает запросы\обращения
namespace Torrent
{
    class Manager
    {
/*#region constants
         const int ServerMinPort = 6881;
         const int ServerMaxPort =  7000;
         const int BlockSize = 16384;
         const int MaxBlocksInProgress = 5;
         const int MaxBlocksInMultiMode = 2;
         const int MaxConnectionPerPeer = 1;
         const int RateControlWindowLength = 10;
         const int RateControlTimerDelay = 1000;
         const int MinimumTimeBeforeRevisit = 30;
         const int MaxUploads = 4;
         const int UploadScheduleInterval = 10000;
         const int EndGamePieces = 5;
#endregion
        */
        List<Peer> Peers { get; set; }
        TrackerClient Request { get; set; }
        TorrentStruct TorFile{ get; set; }
        String DestFolder {get; set; }
        

        private bool IsPortOpening = false;

        public Manager(string TorrentPath, string DestinationFolder)
        {
            TorrentStruct TorrentFile = new TorrentStruct(TorrentPath);//Разбираем торрент-файл
            Console.WriteLine("Торрент файл разобран");

            if (!IsPortOpening) ;
                        //TODO - открыть порт!
            TorFile = TorrentFile;
            
            Request = new TrackerClient(7000);//Создаем запрос
            Console.WriteLine("Отправляю запрос на трекер.");
            Request.parseResponse(getResponseStream(Request, TorrentFile).PreparedStream());
            Console.WriteLine("Запрос отправлен.");
           //string result = Request.sendRequest(TorrentFile.announce, TorrentFile.info_hash, TorrentFile.length, TrackerClient.States.started);
            
            Console.WriteLine("Читаю пиры");
            Caller Worker = new Caller(TorrentFile.Files,TorrentFile.name,TorrentFile.length,TorrentFile.pieceLen,TorrentFile.pieces,TorrentFile.info_hash,Request.Response.SetPerrsArrayFromByteArray());
            Worker.SendHandshakeMessageAndWait();

           
        }

        

        private Stream getResponseStream(TrackerClient Request,TorrentStruct TorrentFile)
        {
            bool SuccessRequest = false;

            Stream GETSteamResult = null/*, GETScrapeStream = null*/;

            try
            {//получаем поток с пирами
                GETSteamResult = Request.sendRequestCompact(TorrentFile.announce, TorrentFile.info_hash, TorrentFile.length, TrackerClient.States.started);

                SuccessRequest = GETSteamResult != null;
            }
            catch (System.Exception ex)
            {//пустой порт/неверный адрес
                Console.WriteLine(ex.Message);

            }
            if (!SuccessRequest)
            {//Если первая попытка не уадалсь - пытаемся пробиться по другим адресам
                int AnnounceIndex = 0;
                while (!SuccessRequest)
                {
                    try
                    {
                        GETSteamResult = Request.sendRequestCompact(TorrentFile.announceList[AnnounceIndex], TorrentFile.info_hash, TorrentFile.length, TrackerClient.States.started);
                        AnnounceIndex++;
                        SuccessRequest = GETSteamResult != null;
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                }
                TorrentFile.ChangeAnnounce(--AnnounceIndex);
            }
            return GETSteamResult;
        }
    }
}
